package com.example.springboot.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.example.springboot.common.AuthAccess;
import com.example.springboot.common.HoneyLogs;
import com.example.springboot.common.LogType;
import com.example.springboot.common.Result;
import com.example.springboot.entity.News;
import com.example.springboot.entity.User;
import com.example.springboot.service.NewsService;
import com.example.springboot.service.UserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 功能：提供接口返回数据
 * 作者：刘涵茹
 * 日期：2024/2/13 15:37
 */

@RestController //返回json,数据的controller注解
public class WebController {
    @Resource//注入对象
    UserService userService;
    @Resource
    NewsService newsService;

    @RequestMapping("/")  //该注解表示这个方法是提供数据的
    public Result hello() {
        return Result.success("success");
    }

    @HoneyLogs(operation = "用户", type = LogType.LOGIN)
    @PostMapping("/login")//登录功能
    public Result login(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUserid()) || StrUtil.isBlank(user.getPassword())) {//StrUtil.isBlank()函数是验证是否为空或null
            return Result.error("用户名或密码为空");
        }
        user = userService.login(user);
        return Result.success(user);
    }

    @AuthAccess//自定义的注解,通过该注解可以将方法中的数据注入容器中,在拦截器class里的方法会收到数据进行判断是否跳过该路径
    //可以和配置拦截器规则配合使用
    @HoneyLogs(operation = "用户", type = LogType.REGISTER)
    @PostMapping("/register")//注册功能
    public Result register(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUserid()) || StrUtil.isBlank(user.getPassword()) || StrUtil.isBlank(user.getRole())) {//StrUtil.isBlank()函数是验证是否为空或null
            return Result.error("用户名或密码为空");
        }
        if (user.getUserid().length() > 10 || user.getPassword().length() > 8) {//用户名不超过10，密码不超过8
            return Result.error("用户名或密码过长");
        }
        user.setCreatedtime(DateUtil.today());
        user = userService.register(user);
        return Result.success(user);
    }

    @AuthAccess//自定义的注解,通过该注解可以将方法中的数据注入容器中,在拦截器class里的方法会收到数据进行判断是否跳过该路径
    //可以和配置拦截器规则配合使用
    @PutMapping("/password")//重置密码
    public Result password(@RequestBody User user) {
        if (StrUtil.isBlank(user.getUserid()) || StrUtil.isBlank(user.getPhone())) {//StrUtil.isBlank()函数是验证是否为空或null
            return Result.error("数据输入不合法");
        }
        userService.resetPassword(user);
        return Result.success();
    }

    /**
     * 统计图数据
     * @return 动态数据
     */
    @GetMapping("/charts")
    public Result charts(){
        //包装数据
        List<User> userList = userService.list();
        List<News> newsList = newsService.list();
        //人数柱状图
        Set<String> roles = userList.stream().map(User::getRole).collect(Collectors.toSet());
        List<Dict> roleList = new ArrayList<>();
        for (String role : roles){
            //统计该类所有的人数
            Long sum = userList.stream().filter(user -> user.getRole().equals(role)).count();
            Dict dict = Dict.create();
            Dict userBar = dict.set("role", role).set("value", sum);
            roleList.add(userBar);
        }
        //竞赛柱状图数据统计//饼图
        //种类去重
        Set<String> signs = newsList.stream().map(News::getSign).collect(Collectors.toSet());
        //统计
        List<Dict> signList = new ArrayList<>();
        for (String sign : signs){
            //统计该类报名的所有人数
            double sum = newsList.stream().filter(news -> news.getSign().equals(sign)).mapToDouble(News::getNum).sum();
            Dict dict = Dict.create();
            Dict signBar = dict.set("name", sign).set("value", sum);
            signList.add(signBar);
        }


        //包装所有数据
        Dict res = Dict.create().set("userBar", roleList).set("signBar", signList);
        return Result.success(res);
    }
}
